﻿using HarfBuzzSharp;
using LightCAD.Core;
using LightCAD.Core.Elements;
using LightCAD.Runtime;
using netDxf.Entities;
using SkiaSharp;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using LightCAD.MathLib;
using Avalonia.Controls;
using Avalonia.Media.TextFormatting.Unicode;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Avalonia.Rendering;

namespace LightCAD.Drawing.Actions
{
    public class MeasureAction : ElementAction
    {
        public static string CommandName;
        public static LcCreateMethod[] CreateMethods;
        private Vector2 StartPoint;
        private Vector2 EndPoint;
        private Vector2 CenterPoint;
        private Vector2 MidPoint;

        private Vector2 LinePoint1;
        private Vector2 LinePoint2;
        private Vector2 LinePoint3;
        private Vector2 LinePoint4;

        private List<Vector2> AreaPoints;
        private double BaseY;
        private bool AreaDone;
        private int index;

        private double Angle;// 弧度，用于显示度数
        private double Radius;
        private double Distance;
        private double Area;
        private double Circumference;
        private string _methodName;

        private enum MeasureDrawType
        {
            None = 0,
            Distance = 1,
            Radius = 2,
            Angle = 3,
            Area = 4
        }
        private MeasureDrawType drawType = MeasureDrawType.None;
        static MeasureAction()
        {
            CommandName = "MEASURE";
            CreateMethods = new LcCreateMethod[5];

            CreateMethods[0] = new LcCreateMethod()
            {
                Name = "NAVIGATE",
                Description = "导航",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep{ Name="Step0", Options="指定测量方式 [距离(L)/半径(R)/角度(A)/面积(E)]:" },
                }
            };

            CreateMethods[1] = new LcCreateMethod()
            {
                Name = "DISTANCE",
                Description = "距离",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep{ Name="Step0", Options="指定第一个点:" },
                    new LcCreateStep{ Name="Step1", Options="指定第二个点:" },
                }
            };

            CreateMethods[2] = new LcCreateMethod()
            {
                Name = "RADIUS",
                Description = "半径",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep{ Name="Step0", Options="选择圆或圆弧:" },
                }
            };

            CreateMethods[3] = new LcCreateMethod()
            {
                Name = "ANGLE",
                Description = "角度",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep{ Name="Step0", Options="选择圆弧、圆、直线:" },
                    new LcCreateStep{ Name="Step1", Options="指定角的第二个端点:" },
                }
            };

            CreateMethods[4] = new LcCreateMethod()
            {
                Name = "AREA",
                Description = "面积",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep{ Name="Step0", Options="指定一个点:" },
                    new LcCreateStep{ Name="Step1", Options="指定下一个点，输入(G)结束:" },
                }
            };
        }

        internal static void Initilize()
        {
        }

        private PointInputer PointInputer { get; set; }
        public MeasureAction() { }
        public MeasureAction(IDocumentEditor docEditor) : base(docEditor)
        {
            this.commandCtrl.WriteInfo("命令 ：MEASURE");
        }
        private LcCreateMethod GetMethod(string method)
        {
            if (method == null) return CreateMethods[0];
            var getted = CreateMethods.FirstOrDefault((m) => m.Name == method);
            if (getted == null)
                return CreateMethods[0];
            else
                return getted;
        }
        public async void ExecCreate(string[] args = null)
        {
            this.StartCreating();
            var method = "NAVIGATE";
            if (args != null && args.Length > 0)
            {
                method = args[0];
            }
            var curMethod = this.GetMethod(method);
            _methodName = curMethod.Name;

            Console.WriteLine(_methodName);

            var ElementInputer = new ElementInputer(this.docEditor);
            this.PointInputer = new PointInputer(this.docEditor);

            if (curMethod.Name == "NAVIGATE") goto Method_NAVIGATE_Step0;
            else if (curMethod.Name == "DISTANCE") goto Method_DISTANCE_Step0;
            else if (curMethod.Name == "RADIUS") goto Method_RADIUS_Step0;
            else if (curMethod.Name == "ANGLE") goto Method_ANGLE_Step0;
            else if (curMethod.Name == "AREA") goto Method_AREA_Step0;
            else goto Method_NAVIGATE_Step0;

            Method_NAVIGATE_Step0:
            curMethod = this.SetCurMethod(CreateMethods, 0);
            var navigate_step0 = curMethod.Steps[0];
            var navigate_result0 = await PointInputer.Execute(navigate_step0.Options);
            if (PointInputer.isCancelled) { this.Cancel(); return; }
            // zcb: 增加Res0为空的判定
            if (navigate_result0 == null)
            {
                this.Cancel();
                goto End;
            }
            if (navigate_result0.ValueX == null)
            {
                if (navigate_result0.Option != null)
                {
                    if (navigate_result0.Option.ToUpper() == "L")
                    {
                        drawType = MeasureDrawType.None;
                        goto Method_DISTANCE_Step0;
                    }
                    else if (navigate_result0.Option.ToUpper() == "R")
                    {
                        drawType = MeasureDrawType.None;
                        goto Method_RADIUS_Step0;
                    }
                    else if (navigate_result0.Option.ToUpper() == "A")
                    {
                        drawType = MeasureDrawType.None;
                        goto Method_ANGLE_Step0;
                    }
                    else if(navigate_result0.Option.ToUpper() == "E")
                    {
                        drawType = MeasureDrawType.None;
                        goto Method_AREA_Step0;
                    }
                    else
                    {
                        goto Method_NAVIGATE_Step0;
                    }
                }
                else
                {
                    goto Method_NAVIGATE_Step0;
                }
            }

        Method_DISTANCE_Step0:
            curMethod = this.SetCurMethod(CreateMethods, 1);
            var distance_step0 = curMethod.Steps[0];
            var distance_result0 = await PointInputer.Execute(distance_step0.Options);
            if (PointInputer.isCancelled) { this.Cancel(); return; }
            // zcb: 增加Res0为空的判定
            if (distance_result0 == null)
            {
                this.Cancel();
                goto End;
            }
            if (distance_result0.ValueX == null)
            {
                if (distance_result0.Option != null)
                {
                    ;
                }
                else
                {
                    this.Distance = -1;
                    goto Method_DISTANCE_Step1;
                }

            }
            else
            {
                this.Distance = -1;
                this.StartPoint = (Vector2)distance_result0.ValueX;
                goto Method_DISTANCE_Step1;
            }

        Method_DISTANCE_Step1:
            this.drawType = MeasureDrawType.Distance;
            var distance_step1 = curMethod.Steps[1];
            var distance_result1 = await PointInputer.Execute(distance_step1.Options);
            if (PointInputer.isCancelled) { this.Cancel(); return; }
            // zcb: 增加Res0为空的判定
            if (distance_result1 == null)
            {
                this.Cancel();
                goto End;
            }
            if (distance_result1.ValueX == null)
            {
                if (distance_result1.Option != null)
                {
                    ;
                }
                else
                {
                    goto Method_NAVIGATE_Step0;
                }
            }
            else
            {
                this.EndPoint = (Vector2)distance_result1.ValueX;
                this.Distance = Vector2.Distance(this.StartPoint, this.EndPoint);
                goto Method_NAVIGATE_Step0;
            }


        Method_RADIUS_Step0:
            curMethod = this.SetCurMethod(CreateMethods, 2);
            var radiud_step0 = curMethod.Steps[0];
            var radius_result0 = await ElementInputer.Execute(radiud_step0.Options);
            if (ElementInputer.isCancelled) { this.Cancel(); return; }
            // zcb: 增加Res0为空的判定
            if (radius_result0 == null)
            {
                this.Cancel();
                goto End;
            }
            if (radius_result0.ValueX == null)
            {
                goto Method_RADIUS_Step0;
            }
            else
            {
                LcElement element = (LcElement)radius_result0.ValueX;
                this.EndPoint = (Vector2)radius_result0.Extent;
                if (element is LcArc || element is LcCircle)
                {
                    if (element is LcArc)
                    {
                        var arc = element as LcArc;
                        this.StartPoint = arc.Center;
                        this.Radius = arc.Radius;
                    }
                    else if (element is LcCircle)
                    {
                        var circle = element as LcCircle;
                        this.StartPoint = circle.Center;
                        this.Radius = circle.Radius;
                    }

                    this.drawType = MeasureDrawType.Radius;
                    goto Method_NAVIGATE_Step0;
                }
                else
                {
                    goto Method_NAVIGATE_Step0;
                }
            }


        Method_ANGLE_Step0:
            curMethod = this.SetCurMethod(CreateMethods, 3);
            var angle_step0 = curMethod.Steps[0];
            var angle_result0 = await ElementInputer.Execute(angle_step0.Options);
            if (ElementInputer.isCancelled) { this.Cancel(); return; }
            // zcb: 增加Res0为空的判定
            if (angle_result0 == null)
            {
                this.Cancel();
                goto End;
            }
            if (angle_result0.ValueX == null)
            {
                goto Method_ANGLE_Step0;
            }
            else
            {
                LcElement element = (LcElement)angle_result0.ValueX;
                this.StartPoint = (Vector2)angle_result0.Extent;
                if (element is LcArc)
                {
                    var arc = element as LcArc;
                    this.CenterPoint = arc.Center;
                    this.Radius = arc.Radius;
                    this.Angle = (arc.EndAngle - arc.StartAngle);
                    if (this.Angle < 0)
                    {
                        this.Angle += Math.PI * 2;//不考虑方向，始终为正
                    }
                    this.StartPoint = arc.Startp;
                    this.EndPoint = arc.Endp;
                    this.MidPoint = arc.Midp;

                    this.drawType = MeasureDrawType.Angle;
                    goto Method_NAVIGATE_Step0;
                }
                else if (element is LcCircle)
                {
                    var circle = element as LcCircle;
                    this.CenterPoint = circle.Center;
                    this.Radius = circle.Radius;
                    goto Method_ANGLE_Step1;
                }
                else if (element is LcLine)
                {
                    var line = element as LcLine;
                    this.Radius = -1;// hack，radius使用负数提示为线
                    this.LinePoint1 = line.Start;
                    this.LinePoint2 = line.End;
                }
                else
                {
                    goto Method_ANGLE_Step0;
                }
            }

        Method_ANGLE_Step1:
            var angle_step1 = curMethod.Steps[1];
            var angle_result1 = await ElementInputer.Execute(angle_step1.Options);
            if (ElementInputer.isCancelled) { this.Cancel(); return; }
            // zcb: 增加Res0为空的判定
            if (angle_result1 == null)
            {
                this.Cancel();
                goto End;
            }
            if (angle_result1.ValueX == null)
            {
                goto Method_ANGLE_Step1;
            }
            else
            {
                LcElement element = (LcElement)angle_result1.ValueX;
                this.EndPoint = (Vector2)angle_result1.Extent;
                // 为圆
                if (this.Radius > 0)
                {
                    // 坐标系变换
                    var first = this.StartPoint - this.CenterPoint;
                    var second = this.EndPoint - this.CenterPoint;

                    // 第二次选择的点不一定处于原来的园上
                    this.EndPoint = Vector2.Polar(this.CenterPoint, this.Radius, second.Angle());

                    var moveang = second.Angle() - first.Angle();
                    this.Angle = moveang;
                    // 只关注大于零，小于180度的角度值
                    if (this.Angle < 0)
                        this.Angle += Math.PI * 2;
                    if (this.Angle > Math.PI)
                        this.Angle = Math.PI * 2 - this.Angle;

                    this.MidPoint = Vector2.RotateInRadian(this.StartPoint, this.CenterPoint, moveang / 2);
                    this.drawType = MeasureDrawType.Angle;
                    goto Method_NAVIGATE_Step0;
                }
                // 为线
                else if (element is LcLine)
                {
                    var line = element as LcLine;
                    this.LinePoint3 = line.Start;
                    this.LinePoint4 = line.End;

                    // 如果两线斜率相同，为平行或者重叠
                    double s1 = (this.LinePoint1.Y - this.LinePoint2.Y) / (this.LinePoint1.X - this.LinePoint2.X);
                    double s2 = (this.LinePoint3.Y - this.LinePoint4.Y) / (this.LinePoint3.X - this.LinePoint4.X);
                    if (Math.Abs(s1 - s2) < double.Epsilon)
                    {
                        goto Method_NAVIGATE_Step0;
                    }

                    // 求交点，并作为度量圆心
                    this.CenterPoint = GetIntersectionOfTwoLines(this.LinePoint1, this.LinePoint2, this.LinePoint3, this.LinePoint4);

                    double d1 = Vector2.Distance(this.CenterPoint, this.LinePoint1);
                    double d2 = Vector2.Distance(this.CenterPoint, this.LinePoint2);
                    this.StartPoint = d1 > d2 ? this.LinePoint2 : this.LinePoint1;

                    double d3 = Vector2.Distance(this.CenterPoint, this.LinePoint3);
                    double d4 = Vector2.Distance(this.CenterPoint, this.LinePoint4);
                    this.EndPoint = d3 > d4 ? this.LinePoint4 : this.LinePoint3;

                    // 坐标系变换
                    var first = this.StartPoint - this.CenterPoint;
                    var second = this.EndPoint - this.CenterPoint;

                    var moveang = second.Angle() - first.Angle();
                    this.Angle = moveang;
                    // 只关注大于零，小于180度的角度值
                    if (this.Angle < 0)
                        this.Angle += Math.PI * 2;
                    if (this.Angle > Math.PI)
                        this.Angle = Math.PI * 2 - this.Angle;

                    this.MidPoint = Vector2.RotateInRadian(this.StartPoint, this.CenterPoint, moveang / 2);
                    this.drawType = MeasureDrawType.Angle;
                    goto Method_NAVIGATE_Step0;
                }
                else
                {
                    goto Method_ANGLE_Step1;
                }
            }


        Method_AREA_Step0:
            curMethod = this.SetCurMethod(CreateMethods, 4);
            var area_step0 = curMethod.Steps[0];
            var area_result0 = await PointInputer.Execute(area_step0.Options);
            if (PointInputer.isCancelled) { this.Cancel(); return; }
            // zcb: 增加Res0为空的判定
            if (area_result0 == null)
            {
                this.Cancel();
                goto End;
            }
            if (area_result0.ValueX == null)
            {
                if (area_result0.Option != null)
                {
                    ;
                }
                goto Method_AREA_Step1;
            }
            else
            {
                ResetArea();
                Vector2 p = (Vector2)area_result0.ValueX;
                AreaPoints.Add(p);
                BaseY = p.Y;
                this.drawType = MeasureDrawType.Area;
                goto Method_AREA_Step1;
            }

        Method_AREA_Step1:
            var area_step1 = curMethod.Steps[1];
            var area_result1 = await PointInputer.Execute(area_step1.Options);
            if (PointInputer.isCancelled) { this.Cancel(); return; }
            // zcb: 增加Res0为空的判定
            if (area_result1 == null)
            {
                this.Cancel();
                goto End;
            }
            if (area_result1.ValueX == null)
            {
                if (area_result1.Option != null && area_result1.Option.ToUpper() == "G")
                {
                    AreaDone = true;
                    goto Method_NAVIGATE_Step0;
                }
                else
                {
                    goto Method_AREA_Step1;
                }
            }
            else
            {
                Vector2 p = (Vector2)area_result1.ValueX;
                AreaPoints.Add(p);
                goto Method_AREA_Step1;
            }

        End:
            this.EndCreating();

        }

        public override void Cancel()
        {
            base.Cancel();
            this.vportRt.SetCreateDrawer(null);
        }
        public override void CreateElement(LcElement element, Matrix3 matrix)
        {

        }
        public override void CreateElement(LcElement element, Vector2 basePoint, double scaleFactor)
        {

        }
        public override void CreateElement(LcElement element, Vector2 basePoint, Vector2 scaleVector)
        {

        }
        public override void Draw(SKCanvas canvas, LcElement element, Matrix3 matrix)
        {

        }

        public override void DrawAuxLines(SKCanvas canvas)
        {
            var mp = this.vportRt.PointerMovedPosition.ToVector2d();
            var wcs_mp = this.vportRt.ConvertScrToWcs(mp);

            if (drawType == MeasureDrawType.Distance)
            {
                DrawDistance(canvas, wcs_mp);
            }
            else if (drawType == MeasureDrawType.Radius)
            {
                DrawRadius(canvas);
            }
            else if (drawType == MeasureDrawType.Angle)
            {
                DrawAngle(canvas);
            }
            else if(drawType == MeasureDrawType.Area)
            {
                DrawArea(canvas, wcs_mp); 
            }
            else
            {
                ;
            }
        }

        private void DrawAuxLine(SKCanvas canvas, Vector2 p0, Vector2 p1)
        {
            var sk_pre = this.vportRt.ConvertWcsToScr(p0).ToSKPoint();
            var sk_p = this.vportRt.ConvertWcsToScr(p1).ToSKPoint();
            //辅助元素的颜色 
            canvas.DrawLine(sk_pre, sk_p, new SKPaint { Color = this.vportRt.GetAuxColorValue(), IsStroke = true });
            //辅助曲线的颜色，包括辅助长度，辅助角度等
        }

        private void DrawDistance(SKCanvas canvas, Vector2 mp)
        {
            var startp = this.StartPoint;
            var endp = mp;
            if (this.Distance > 0)
            {
                endp = this.EndPoint;
            }

            var start = this.vportRt.ConvertWcsToScr(startp).ToSKPoint();
            var end = this.vportRt.ConvertWcsToScr(endp).ToSKPoint();

            canvas.DrawLine(start, end, Constants.auxElementPen);

            if (this.Distance > 0)
            {
                var midp = (startp + endp) / 2;
                var doc = this.docRt.Document;
                LcText text = doc.CreateObject<LcText>();
                text.Start = midp;
                text.TextStart = midp;
                text.Heigh = 500;// this.raduis * 2 / 20 < 1 ? 1 : Math.Round(this.raduis * 2 / 20);
                text.Text = (this.Distance).ToString("0.00");
                text.Rotate = 180 / Math.PI * (endp - startp).Angle();
                text.Alignment = "居中";
                text.Widthfactor = 1;
                text.Tilt = 0;

                var eleAction = (text.RtAction as ElementAction);
                Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
                eleAction.SetViewport(this.vportRt).Draw(canvas, text, matrix);
            }
        }

        private void DrawRadius(SKCanvas canvas)
        {
            var start = this.vportRt.ConvertWcsToScr(this.StartPoint).ToSKPoint();
            var end = this.vportRt.ConvertWcsToScr(this.EndPoint).ToSKPoint();

            var doc = this.docRt.Document;
            LcText text = doc.CreateObject<LcText>();
            text.Start = this.EndPoint;
            text.TextStart = this.EndPoint;
            text.Heigh = 500;// this.raduis * 2 / 20 < 1 ? 1 : Math.Round(this.raduis * 2 / 20);
            text.Text = (this.Radius).ToString("0.00");
            text.Rotate = 180 / Math.PI * (this.EndPoint - this.StartPoint).Angle();
            text.Alignment = "居中";
            text.Widthfactor = 1;
            text.Tilt = 0;

            Vector2 direction = new Vector2(this.EndPoint.X - this.StartPoint.X, this.EndPoint.Y - this.StartPoint.Y);
            double dis = Math.Abs(text.Width);
            Vector2 lidisptpos = this.EndPoint + (new Vector2(direction.X * dis, direction.Y * dis)) / Math.Sqrt(Math.Abs((Math.Pow(direction.X, 2.0) + Math.Pow(direction.Y, 2.0))));

            var newend = this.vportRt.ConvertWcsToScr(lidisptpos).ToSKPoint();

            canvas.DrawLine(start, end, Constants.auxElementPen);
            canvas.DrawLine(start, newend, Constants.auxElementPen);

            var eleAction = (text.RtAction as ElementAction);
            Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
            eleAction.SetViewport(this.vportRt).Draw(canvas, text, matrix);
        }

        private void DrawAngle(SKCanvas canvas)
        {
            var start = this.vportRt.ConvertWcsToScr(this.StartPoint).ToSKPoint();
            var end = this.vportRt.ConvertWcsToScr(this.EndPoint).ToSKPoint();
            var center = this.vportRt.ConvertWcsToScr(this.CenterPoint).ToSKPoint();

            var doc = this.docRt.Document;
            LcText text = doc.CreateObject<LcText>();
            text.Start = this.MidPoint;
            text.TextStart = this.MidPoint;
            text.Heigh = 500;// this.raduis * 2 / 20 < 1 ? 1 : Math.Round(this.raduis * 2 / 20);
            text.Text = (this.Angle * 180 / Math.PI).ToString("0.00");
            text.Rotate = 180 / Math.PI * (this.EndPoint - this.StartPoint).Angle();
            text.Alignment = "居中";
            text.Widthfactor = 1;
            text.Tilt = 0;

            canvas.DrawLine(center, start, Constants.auxElementPen);
            canvas.DrawLine(center, end, Constants.auxElementPen);

            var eleAction = (text.RtAction as ElementAction);
            Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
            eleAction.SetViewport(this.vportRt).Draw(canvas, text, matrix);
        }

        private void DrawArea(SKCanvas canvas, Vector2 mp)
        {
            if (AreaPoints.Count() < 1)
            {
                index = AreaPoints.Count();
                return;
            }
                
            else if(AreaPoints.Count() == 1)
            {
                var start = this.vportRt.ConvertWcsToScr(AreaPoints.ElementAt(0)).ToSKPoint();
                var mid = this.vportRt.ConvertWcsToScr(mp).ToSKPoint();
                canvas.DrawLine(start, mid, Constants.auxElementPen);     
            }
            else if(AreaPoints.Count() == 2)
            {
                var start = this.vportRt.ConvertWcsToScr(AreaPoints.ElementAt(0)).ToSKPoint();
                var end = this.vportRt.ConvertWcsToScr(AreaPoints.ElementAt(1)).ToSKPoint();
                var mid = this.vportRt.ConvertWcsToScr(mp).ToSKPoint();

                canvas.DrawLine(start, mid, Constants.auxElementPen);
                canvas.DrawLine(end, mid, Constants.auxElementPen);
                canvas.DrawLine(start, end, Constants.auxElementPen);
            }
            else
            {
                int last_ele = AreaPoints.Count() - 1;
                for (int i = 0; i < AreaPoints.Count(); i++)
                {
                    var end = this.vportRt.ConvertWcsToScr(AreaPoints.ElementAt(i)).ToSKPoint();
                    if (i == last_ele)
                    {
                        // 当完成所有点输入，结束预览
                        if (AreaDone)
                        {
                            var start = this.vportRt.ConvertWcsToScr(AreaPoints.ElementAt(0)).ToSKPoint();
                            canvas.DrawLine(start, end, Constants.auxElementPen);

                            // 未把move point计算在内
                            CalculateArea();

                            var doc = this.docRt.Document;
                            LcText text = doc.CreateObject<LcText>();
                            text.Start = AreaPoints.ElementAt(0);
                            text.TextStart = AreaPoints.ElementAt(0);
                            text.Heigh = 500;
                            text.Text = "面积:" + (Area).ToString("0.00") + ", " + "周长:" + Circumference.ToString("0.00");
                            text.Rotate = 0;
                            text.Alignment = "居中";
                            text.Widthfactor = 1;
                            text.Tilt = 0;

                            var eleAction = (text.RtAction as ElementAction);
                            Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
                            eleAction.SetViewport(this.vportRt).Draw(canvas, text, matrix);
                        }
                        else
                        {
                            var first = this.vportRt.ConvertWcsToScr(AreaPoints.ElementAt(0)).ToSKPoint();
                            var mid = this.vportRt.ConvertWcsToScr(mp).ToSKPoint();
                            canvas.DrawLine(first, mid, Constants.auxElementPen);
                            canvas.DrawLine(end, mid, Constants.auxElementPen);
                        }
                    }
                    else
                    {
                        var start = this.vportRt.ConvertWcsToScr(AreaPoints.ElementAt(i+1)).ToSKPoint();
                        canvas.DrawLine(start, end, Constants.auxElementPen);
                    }            
                }
            }
        }

        /// <summary>
        /// 获取两条线的夹角  
        /// </summary>
        /// <param name="line1start"></param>
        /// <param name="line1End"></param>
        /// <param name="line2start"></param>
        /// <param name="line2End"></param>
        /// <returns></returns>
        public double GetDegreesByTwoLine(Vector2 line1start, Vector2 line1End, Vector2 line2start, Vector2 line2End)
        {
            double x1 = line1start.X;
            double y1 = line1start.Y;
            double x2 = line1End.X;
            double y2 = line1End.Y;
            double x3 = line2start.X;
            double y3 = line2start.Y;
            double x4 = line2End.X;
            double y4 = line2End.Y;
            // 计算线段的向量表示
            double v1x = x2 - x1;
            double v1y = y2 - y1;
            double v2x = x4 - x3;
            double v2y = y4 - y3;
            // 计算向量的内积
            double dotProduct = v1x * v2x + v1y * v2y;
            // 计算向量的长度
            double magnitudeV1 = Math.Sqrt(v1x * v1x + v1y * v1y);
            double magnitudeV2 = Math.Sqrt(v2x * v2x + v2y * v2y);
            // 计算夹角余弦值
            double cosine = dotProduct / (magnitudeV1 * magnitudeV2);
            // 将夹角余弦值转换为角度
            double angleRadians = Math.Acos(cosine);
            double angleDegrees = angleRadians * 180 / Math.PI;
            return angleDegrees;
        }

        public Vector2 GetIntersectionOfTwoLines(Vector2 line1start, Vector2 line1End, Vector2 line2start, Vector2 line2End)
        {
            double x1 = line1start.X;
            double y1 = line1start.Y;
            double x2 = line1End.X;
            double y2 = line1End.Y;
            double x3 = line2start.X;
            double y3 = line2start.Y;
            double x4 = line2End.X;
            double y4 = line2End.Y;
            // 计算线段的向量表示
            double px = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));
            double py = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));
            return new Vector2(px, py);
        }

        private void CalculateArea()
        {
            Area = 0.0;
            Circumference = 0.0;
            if (AreaPoints.Count() < 3)
                return;

            Vector2 p1 = AreaPoints.ElementAt(0);
            for (int i = 0; i < AreaPoints.Count(); ++i)
            {
                Vector2 p2 = AreaPoints.ElementAt((i + 1) % AreaPoints.Count());
                Area += CalcSubArea(p1, p2);
                Circumference += p1.DistanceTo(p2);
                p1 = p2;
            }
   
            Area = 0.5 * Math.Abs(Area);
        }

        private double CalcSubArea(Vector2 p1, Vector2 p2)
        {
            double width = p2.X - p1.X;
            double height = (p1.Y - BaseY) + (p2.Y - BaseY);

            return width * height;
        }

        private void ResetArea()
        {
            AreaPoints = new List<Vector2>();
            //AreaPoints.Clear();
            Area = 0.0;
            Circumference = 0.0;
            BaseY = 0.0;
            AreaDone = false;
        }

        #region Grip
        public override ControlGrip[] GetControlGrips(LcElement element)
        {
            var grips = new List<ControlGrip>();
            return grips.ToArray();
        }

        public override void SetDragGrip(LcElement element, string gripName, Vector2 position, bool isEnd)
        {

        }


        public override void DrawDragGrip(SKCanvas canvas)
        {

        }

        #endregion

        public override List<PropertyObserver> GetPropertyObservers()
        {
            return new List<PropertyObserver>()
            {

            };
        }
    }
}
